package com.jinly.ryder.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileUtil {

    public static boolean existsFile(String fileName) {
        if (fileName.startsWith("~")) {
            fileName = fileName.replace("~", System.getProperty("user.home"));
        }
        File file = new File(fileName);
        return file.exists();
    }

    public static void createDir(String dir) {
        if (dir.startsWith("~")) {
            dir = dir.replace("~", System.getProperty("user.home"));
        }
        File file = new File(dir);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    public static void createFile(String fileName, byte[] input) {
        if (fileName.startsWith("~")) {
            fileName = fileName.replace("~", System.getProperty("user.home"));
        }
        File file = new File(fileName);
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            if (!file.exists()) {
                log.debug("创建文件:{}", file.getAbsolutePath());
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                file.createNewFile();
            }
            log.debug("开始写入文件:{}", file.getAbsolutePath());
            inputStream = new ByteArrayInputStream(input);
            outputStream = new FileOutputStream(file);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                outputStream.write(buf, 0, len);
            }
            outputStream.flush();
        } catch (Exception e) {
            log.warn("创建部署文件失败", e);
            if (file.exists()) {
                file.deleteOnExit();
            }
            throw new RuntimeException("创建部署文件" + fileName + "失败");
        } finally {
            closeIO(inputStream, outputStream);
        }

    }

    public static byte[] getContent(String fileName) {
        if (fileName.startsWith("~")) {
            fileName = fileName.replace("~", System.getProperty("user.home"));
        }
        File file = new File(fileName);
        FileInputStream fi = null;
        byte[] buffer = new byte[(int) file.length()];
        try {
            fi = new FileInputStream(file);
            int offset = 0;
            int numRead = 0;
            while (offset < buffer.length
                    && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
                offset += numRead;
            }
            // 确保所有数据均被读取
            if (offset != buffer.length) {
                throw new IOException("Could not completely read file " + file.getName());
            }
        } catch (Exception e) {
            throw new RuntimeException("Could not completely read file " + file.getName());
        } finally {
            closeIO(fi);
        }
        return buffer;
    }

    public static void closeIO(Closeable... closeables) {
        try {
            if (closeables != null) {
                for (Closeable closeable : closeables) {
                    if (closeable != null) closeable.close();
                }
            }
        } catch (Exception e) {
        }
    }

    public static boolean delete(String name) {
        File file = new File(name);
        log.debug("开始删除文件:[{}]{}", file.exists(), name);
        if (file.exists()) {
            if (file.isDirectory()) {
                for (String f : file.list()) {
                    if (!delete(file.getAbsolutePath() + "/" + f)) {
                        return false;
                    }
                }
            }
            return file.delete();
        }
        return true;
    }

    public static String pathAppend(String... paths) {
        String full = "";
        for (String path : paths) {
            String append = path;
            if (full.endsWith("/") && path.startsWith("/")) {
                append = path.substring(1);
            } else if (!full.endsWith("/") && !path.startsWith("/")) {
                append = "/" + path;
            }
            full += append;
        }
        return full;
    }

    public static void fileWrite(File file, OutputStream out) {
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(file));
            byte[] buf = new byte[4096];
            int len;
            while ((len = bis.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
        } catch (Exception e) {
            throw new RuntimeException("file write error", e);
        } finally {
            closeIO(out, bis);
        }

    }

    public static File zipFile(File file) {
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        ZipOutputStream out = null;
        File zipFile = new File(file.getPath() + ".zip");
        try {
            out = new ZipOutputStream(new FileOutputStream(zipFile));
            bos = new BufferedOutputStream(out);
            bis = new BufferedInputStream(new FileInputStream(file));
            out.putNextEntry(new ZipEntry(file.getName()));
            byte[] buf = new byte[4096];
            int len;
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf, 0, len);
            }
            return zipFile;
        } catch (Exception e) {
            throw new RuntimeException("zip file error", e);
        } finally {
            closeIO(bos, out, bis);
        }
    }
}
